//==========================================================================
// Copyright (c) 2000-2006,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <xllp_lcd.h>
#include <bulverde.h>
#include "display_def.h"
#include <udelay.h>
#define SPI_SCLK    36
#define SPI_TXD     13
#define SPI_FRM     14
#define SPI_RXD     11

#define LCD_nRESET  24
#define LCD_RS      77


// GPIO
#define GPIO_PIN_IN 0
#define GPIO_PIN_OUT    1

#define GPIO_AS_GPIO    0
#define GPIO_AS_AF1 1
#define GPIO_AS_AF2 2
#define GPIO_AS_AF3 3

void Gpio_SetDir(int gpio_num, int direction);
void Gpio_SetAFR(int gpio_num, int function);
void Gpio_SetOutLow(int gpio_num);
void Gpio_SetOutHigh(int gpio_num);

static void SPI2Init(void)
{
    #define CKEN3_SSP2      (1 << 3)    /* SSP2 Unit Clock Enable */
    CKEN |= CKEN3_SSP2;

    Gpio_SetDir(SPI_SCLK, GPIO_PIN_OUT);
    Gpio_SetAFR(SPI_SCLK, GPIO_AS_AF2);
    //set spi_txd
    Gpio_SetDir(SPI_TXD, GPIO_PIN_OUT);
    Gpio_SetAFR(SPI_TXD, GPIO_AS_AF1);
    //set spi_frm  SPI_CS -- must be GPIO only because of the polarity of CS -- must be high for PMIC active
    Gpio_SetDir(SPI_FRM, GPIO_PIN_OUT);
    Gpio_SetAFR(SPI_FRM, GPIO_AS_GPIO);


    SSCR0_2 = (unsigned long)0x00d00407;//Samsung spi 24bits

    SSCR1_2 = (unsigned long)0x100007D8;

    SSCR0_2 |= SSCR0_SSE;

}

void LcdHWSetup(void)
{
    int gpio_x;

    for( gpio_x = 58; gpio_x <= 76 ; gpio_x++ )
    {
            Gpio_SetDir( gpio_x, GPIO_PIN_OUT );
            Gpio_SetOutLow(gpio_x);
            Gpio_SetAFR( gpio_x, GPIO_AS_AF2 );
    }

    Gpio_SetDir( 77, GPIO_PIN_OUT );
    Gpio_SetAFR( 77, GPIO_AS_AF2 );

    Gpio_SetDir( 86, GPIO_PIN_OUT );
    Gpio_SetOutLow(86);
    Gpio_SetAFR( 86, GPIO_AS_AF2 );

    Gpio_SetDir( 87, GPIO_PIN_OUT );
    Gpio_SetOutLow(87);
    Gpio_SetAFR( 87, GPIO_AS_AF2 );
}

static void LcdReset(void)
{
    Gpio_SetDir(LCD_nRESET, GPIO_PIN_OUT);
    Gpio_SetAFR(LCD_nRESET, GPIO_AS_GPIO);

    Gpio_SetOutHigh(LCD_nRESET);

    ostdelay(20 * 1000);

    Gpio_SetOutLow(LCD_nRESET);

    ostdelay(20 * 1000);

    Gpio_SetOutHigh(LCD_nRESET);


}

void SPIWrite(unsigned long data)
{

    SSCR0_2 |= SSCR0_SSE;

    Gpio_SetOutLow(SPI_FRM);

    SSDR_2 = data;

    SSCR0_2 |= SSCR0_SSE;

    while( SSSR_2 & SSSR_BSY ) { };

    Gpio_SetOutHigh(SPI_FRM);
}

void LcdWriteIndx(unsigned long data)
{
    data |= (0x70 << 16);
    SPIWrite(data);
}

void LcdWriteData(unsigned long data)
{
    data |= (0x72 << 16);
    SPIWrite(data);
}

void LcdSamsungInit(void)
{
    //Start the oscillation circuit
    LcdWriteIndx(0x0000);
    LcdWriteData(0x0001);

    ostdelay(10*1000);

    //Display off
    LcdWriteIndx(0x0007);
    LcdWriteData(0x0004);

    //VCL1 setting
    LcdWriteIndx(0x0011);//Power control 2
    LcdWriteData(0x3f04);

    //1'VcomH setting;  2'Amplitude of VCOM setting
    LcdWriteIndx(0x0014);//Power control 5
    LcdWriteData(0x2420);

    //POWER CONTROL 1 setting
    LcdWriteIndx(0x0010);
    LcdWriteData(0x1b00);

    //POWER CONTROL 4 setting
    LcdWriteIndx(0x0013);
    LcdWriteData(0x0040);

    //POWER CONTROL 4 setting
    LcdWriteIndx(0x0013);
    LcdWriteData(0x0060);

    //POWER CONTROL 4 setting
    LcdWriteIndx(0x0013);
    LcdWriteData(0x0070);

    //Specifies 262k-color mode
    LcdWriteIndx(0x0001);//Driver output control
    LcdWriteData(0x1927);

    //The line inversion waveform is set
    LcdWriteIndx(0x0002);//LCD-Driving-Waveform Control
    LcdWriteData(0x0700);

    //262k-color mode
    LcdWriteIndx(0x0003);//Entry Mode
    LcdWriteData(0x1030);

    //Front/Back Porch setting
    LcdWriteIndx(0x0008);//Display control 2
    LcdWriteData(0x0808);

    //External clock setting
    LcdWriteIndx(0x000b);//Frame Cycle Control
    LcdWriteData(0x0620);

    //18-bit RGB interface setting
    LcdWriteIndx(0x000c);//External Display Interface
    LcdWriteData(0x0110);

    //Gage Out operation
    LcdWriteIndx(0x0007);//Display control
    LcdWriteData(0x0015);

    //Source output Normal Display
    LcdWriteIndx(0x0007);//Display control
    LcdWriteData(0x0017);

    //RAM Address Set
    LcdWriteIndx(0x0020);//
    LcdWriteData(0x0000);

    //RAM Address Set
    LcdWriteIndx(0x0021);//
    LcdWriteData(0x0000);

    //Gamma setting
    LcdWriteIndx(0x0030);
    LcdWriteData(0x0000);

    LcdWriteIndx(0x0031);
    LcdWriteData(0x0000);

    LcdWriteIndx(0x0032);
    LcdWriteData(0x0000);

    LcdWriteIndx(0x0033);
    LcdWriteData(0x0000);

    LcdWriteIndx(0x0034);
    LcdWriteData(0x4440);

    LcdWriteIndx(0x0035);
    LcdWriteData(0x0110);

    LcdWriteIndx(0x0036);
    LcdWriteData(0x0014);

    LcdWriteIndx(0x0037);
    LcdWriteData(0x1f0e);

    LcdWriteIndx(0x0038);
    LcdWriteData(0x0000);

    LcdWriteIndx(0x0039);
    LcdWriteData(0x0000);

    //Write Data to GRAM
    LcdWriteIndx(0x0022);
    //LcdWriteData(0x0000);

}

///////////////////////////////////////////////////////////////////////////////

void Lcm_SetupGPIOs(DisplayContext *pCxt)
{
    // 16bpp support
    // bits 58-77
    GPDR1 |= (0x3f << 26);
    GPDR2 |= 0x00003fff;

    GAFR1_U = (GAFR1_U & ~(0xfff << 20)) | (0xaaa << 20);
    GAFR2_L = (GAFR2_L & 0xf0000000) | 0x0aaaaaaa;
}

void Lcm_DisplayOn(DisplayContext *pCxt)
{
    SPI2Init();
    LcdHWSetup();
    LcdReset();
    ostdelay(20 * 1000);
    LcdSamsungInit();
}

void Lcm_DisplayOff(DisplayContext *pCxt)
{
}

void LcdCtrl_Init_Sub(int val_BPP, int PCD, int PixelDataFormat)
{
    PCD = 7;

    // s6d0139
    LCCR1 = (LCD_PPL(0xEF) | LCD_HSW(0x5) |
            LCD_ELW(0x1)  | LCD_BLW(0x1) );

    LCCR2 = (LCD_LPP(0x13f) | LCD_VSW(0x5) |
            LCD_EFW(0x1)  | LCD_BFW(0x1) );
    LCCR3 = (LCD_PCD(PCD)  | LCD_BPP(val_BPP) | LCD_PCP | LCD_VSP | LCD_HSP |
            LCD_PDFOR(PixelDataFormat));
//    LCCR3 = 0x04800008;
}

